"""
交互式会话模块

提供多轮对话会话管理功能。
"""

import cmd
import os
import shlex
import readline
from typing import List, Optional

from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
from rich.syntax import Syntax
from rich.text import Text

from .ai import ModelFactory
from .core.context import ContextManager
from .core.file_manager import FileManager
from .core.prompt_builder import PromptBuilder
from .core.session_manager import SessionManager
from .core.project_analyzer import ProjectAnalyzer
from .core.project_generator import ProjectGenerator
from .utils.config import Config
from .agent import MiniCoderAgent
from .tools import ToolManager

console = Console()


class InteractiveSession(cmd.Cmd):
    """交互式会话类"""
    
    intro = "欢迎使用 MiniCoder CLI 交互式会话！输入 'help' 查看可用命令。"
    prompt = "minicoder> "
    
    def __init__(self, config: Config, stream: bool = False, agent_mode: bool = True) -> None:
        super().__init__()
        self.config = config
        self.stream = stream
        self.agent_mode = agent_mode
        self.context_manager = ContextManager()
        self.file_manager = FileManager()
        self.prompt_builder = PromptBuilder()
        
        # 初始化会话管理器
        self.session_manager = SessionManager()
        
        # 初始化项目分析器和生成器
        self.project_analyzer = ProjectAnalyzer()
        self.project_generator = ProjectGenerator()
        
        # 创建AI模型实例
        try:
            self.ai_model = ModelFactory.create_model(config)
        except Exception as e:
            console.print(f"[red]AI模型初始化失败: {e}[/red]")
            raise
        
        # 初始化工具管理器和 Agent
        if self.agent_mode:
            try:
                self.tool_manager = ToolManager()
                self.agent = MiniCoderAgent(self.ai_model, self.tool_manager)
                console.print("[green]🤖 Agent 模式已启用 - 可以自主调用工具[/green]")
            except Exception as e:
                console.print(f"[yellow]⚠️ Agent 模式初始化失败，将使用传统模式: {e}[/yellow]")
                self.agent_mode = False
                self.tool_manager = None
                self.agent = None
        else:
            self.tool_manager = None
            self.agent = None
        
        # 会话历史（保持向后兼容）
        self.history: List[dict] = []
        
        # 检查是否在项目目录中
        if self.session_manager.is_project_initialized():
            # 自动创建或加载会话
            self._initialize_session()
        else:
            console.print("[yellow]💡 提示: 运行 'minicoder init --project' 初始化项目工作目录以启用会话持久化[/yellow]")
        
        # 设置命令提示符
        stream_indicator = " (stream)" if stream else ""
        project_indicator = " [项目]" if self.session_manager.is_project_initialized() else ""
        agent_indicator = " [Agent]" if self.agent_mode else ""
        self.prompt = f"minicoder({self.config.get_provider()}){stream_indicator}{project_indicator}{agent_indicator}> "
        
        # 初始化 readline 可用性标志
        self.readline_available = False
    
    def _initialize_session(self) -> None:
        """初始化会话"""
        # 检查是否有最近的会话
        sessions = self.session_manager.list_sessions()
        
        if sessions:
            # 询问是否加载最近的会话
            recent_session = sessions[0]
            console.print(f"[dim]发现最近会话: {recent_session['name']} ({recent_session['message_count']} 条消息)[/dim]")
            console.print("[dim]按 Enter 加载最近会话，或输入 'new' 创建新会话[/dim]")
            
            # 这里简化处理，直接加载最近会话
            self.session_manager.load_session(recent_session['id'])
        else:
            # 创建新会话
            self.session_manager.create_session()
    
    def do_help(self, arg: str) -> None:
        """显示帮助信息"""
        help_text = """
[bold]可用命令:[/bold]

[green]对话命令:[/green]
  [prompt]          直接输入提示词进行对话
  /ask <prompt>     发送提示词并获取响应
  /clear            清空会话历史
  /history          显示会话历史

[green]文件操作:[/green]
  /include <file>   将文件内容加载到上下文中
  /exclude <file>   从上下文中移除文件
  /files            显示当前包含的文件
  /read <file>      读取并显示文件内容
  /write <file>     将AI响应写入文件

[green]会话管理:[/green]
  /session          显示当前会话信息
  /sessions         列出所有会话
  /load <session>   加载指定会话
  /new              创建新会话
  /checkpoint <name> 创建检查点
  /restore <id>     恢复检查点

[green]聊天管理:[/green]
  /chat save <tag>  保存当前会话状态
  /chat resume <tag> 恢复指定会话
  /chat list        列出可用的会话标签
  /chat delete <tag> 删除指定会话

[green]目录管理:[/green]
  /directory add <path> 添加目录到工作空间
  /directory show      显示所有工作空间目录

[green]内存管理:[/green]
  /memory add <text>   添加文本到AI内存（自动分类和标记）
  /memory show [--category=分类] [--importance=级别] [--tags=标签] 显示记忆条目
  /memory refresh      刷新内存内容（清理低价值条目）
  /memory delete <id>  删除指定记忆条目
  /memory stats        显示内存统计信息

[green]配置命令:[/green]
  /config           显示当前配置
  /model <name>     切换AI模型
  /provider <name>  切换AI提供商
  /settings         打开设置编辑器

[green]项目生成:[/green]
  /generate <description>  智能生成项目（根据描述自动分析并生成代码）
  /analyze <description>   分析项目需求（显示项目分析结果）
  /templates              显示可用的项目模板

[green]工具命令:[/green]
  /tools            显示可用工具
  /copy             复制最后输出到剪贴板
  /stats            显示会话统计信息
  /about            显示版本信息

[green]Agent 命令:[/green]
  /agent            显示 Agent 状态
  /agent status     显示 Agent 状态
  /agent history    显示 Agent 对话历史
  /agent clear      清空 Agent 历史
  /agent suggest <query>  建议合适的工具
  /mode             显示当前模式
  /mode agent       切换到 Agent 模式
  /mode traditional 切换到传统模式

[green]系统命令:[/green]
  /quit, /exit      退出会话
  /clear            清屏
  /help, /?         显示此帮助信息
  /init             初始化项目工作目录
  /complete <text>  手动补全命令（当 Tab 键不可用时）
  /autocomplete     显示自动补全状态和帮助

[dim]提示: 直接输入文本将作为提示词发送给AI[/dim]
[dim]💡 在项目目录中运行 'minicoder init --project' 启用会话持久化[/dim]
[dim]🔧 自动补全: 输入 '/' 后按 Tab 查看命令，输入 '/mem' 后按 Tab 补全为 '/memory'[/dim]
[dim]💡 如果 Tab 键不工作，使用 /complete <text> 手动补全命令[/dim]
        """
        console.print(Panel(help_text, title="MiniCoder CLI 帮助", border_style="blue"))
    
    def do_ask(self, arg: str) -> None:
        """发送提示词并获取响应"""
        if not arg.strip():
            console.print("[yellow]请输入提示词[/yellow]")
            return
        
        self._process_prompt(arg.strip())
    
    def do_include(self, arg: str) -> None:
        """将文件内容加载到上下文中"""
        if not arg.strip():
            console.print("[yellow]请指定文件路径[/yellow]")
            return
        
        try:
            file_path = arg.strip()
            content = self.file_manager.read_file(file_path)
            self.context_manager.add_file(file_path, content)
            
            # 保存到持久化会话
            if self.session_manager.is_project_initialized():
                self.session_manager.add_context_file(file_path, content)
            
            console.print(f"[green]已加载文件: {file_path}[/green]")
        except Exception as e:
            console.print(f"[red]文件加载失败: {e}[/red]")
    
    def do_exclude(self, arg: str) -> None:
        """从上下文中移除文件"""
        if not arg.strip():
            console.print("[yellow]请指定文件路径[/yellow]")
            return
        
        try:
            file_path = arg.strip()
            self.context_manager.remove_file(file_path)
            console.print(f"[green]已移除文件: {file_path}[/green]")
        except Exception as e:
            console.print(f"[red]文件移除失败: {e}[/red]")
    
    def do_files(self, arg: str) -> None:
        """显示当前包含的文件"""
        files = self.context_manager.get_files()
        if not files:
            console.print("[dim]当前没有包含的文件[/dim]")
            return
        
        console.print("[bold]当前包含的文件:[/bold]")
        for file_path in files:
            console.print(f"  • {file_path}")
    
    def do_read(self, arg: str) -> None:
        """读取并显示文件内容"""
        if not arg.strip():
            console.print("[yellow]请指定文件路径[/yellow]")
            return
        
        try:
            file_path = arg.strip()
            content = self.file_manager.read_file(file_path)
            
            # 尝试语法高亮
            try:
                syntax = Syntax(content, "python", theme="monokai")
                console.print(syntax)
            except:
                console.print(content)
                
        except Exception as e:
            console.print(f"[red]文件读取失败: {e}[/red]")
    
    def do_write(self, arg: str) -> None:
        """将AI响应写入文件"""
        if not arg.strip():
            console.print("[yellow]请指定文件路径[/yellow]")
            return
        
        if not self.history:
            console.print("[yellow]没有可写入的响应[/yellow]")
            return
        
        try:
            file_path = arg.strip()
            last_response = self.history[-1]["response"]
            self.file_manager.write_file(file_path, last_response)
            console.print(f"[green]响应已写入文件: {file_path}[/green]")
        except Exception as e:
            console.print(f"[red]文件写入失败: {e}[/red]")
    
    def do_clear(self, arg: str) -> None:
        """清空会话历史"""
        self.history.clear()
        self.context_manager.clear()
        console.print("[green]会话历史已清空[/green]")
    
    def do_history(self, arg: str) -> None:
        """显示会话历史"""
        if not self.history:
            console.print("[dim]没有会话历史[/dim]")
            return
        
        console.print("[bold]会话历史:[/bold]")
        for i, item in enumerate(self.history, 1):
            console.print(f"\n[cyan]{i}. 用户:[/cyan] {item['prompt']}")
            console.print(f"[green]AI:[/green] {item['response'][:100]}...")
    
    def do_config(self, arg: str) -> None:
        """显示当前配置"""
        info = self.ai_model.get_model_info()
        console.print("[bold]当前配置:[/bold]")
        console.print(f"  提供商: {info['provider']}")
        console.print(f"  模型: {info['model']}")
        console.print(f"  状态: {'可用' if info['available'] else '不可用'}")
    
    def do_model(self, arg: str) -> None:
        """切换AI模型"""
        if not arg.strip():
            console.print("[yellow]请指定模型名称[/yellow]")
            return
        
        try:
            self.config.set_model(arg.strip())
            # 重新创建AI模型实例
            self.ai_model = ModelFactory.create_model(self.config)
            console.print(f"[green]已切换到模型: {arg.strip()}[/green]")
        except Exception as e:
            console.print(f"[red]模型切换失败: {e}[/red]")
    
    def do_provider(self, arg: str) -> None:
        """切换AI提供商"""
        if not arg.strip():
            console.print("[yellow]请指定提供商名称[/yellow]")
            return
        
        try:
            self.config.set_provider(arg.strip())
            # 重新创建AI模型实例
            self.ai_model = ModelFactory.create_model(self.config)
            console.print(f"[green]已切换到提供商: {arg.strip()}[/green]")
        except Exception as e:
            console.print(f"[red]提供商切换失败: {e}[/red]")
    
    def do_session(self, arg: str) -> None:
        """显示当前会话信息"""
        if not self.session_manager.is_project_initialized():
            console.print("[yellow]当前不在项目目录中，无法显示会话信息[/yellow]")
            return
        
        session_info = self.session_manager.get_session_info()
        if not session_info:
            console.print("[yellow]没有活动会话[/yellow]")
            return
        
        info_text = f"""
[bold]会话信息:[/bold]
• ID: {session_info['id']}
• 名称: {session_info['name']}
• 创建时间: {session_info['created']}
• 最后更新: {session_info['last_updated']}
• 消息数量: {session_info['message_count']}
• 上下文文件: {session_info['context_files_count']}
• 项目目录: {session_info['project_dir']}
        """
        console.print(Panel(info_text.strip(), title="当前会话", border_style="green"))
    
    def do_sessions(self, arg: str) -> None:
        """列出所有会话"""
        if not self.session_manager.is_project_initialized():
            console.print("[yellow]当前不在项目目录中，无法列出会话[/yellow]")
            return
        
        sessions = self.session_manager.list_sessions()
        if not sessions:
            console.print("[dim]没有找到会话[/dim]")
            return
        
        from rich.table import Table
        table = Table(title="会话列表", show_header=True, header_style="bold magenta")
        table.add_column("名称", style="cyan")
        table.add_column("消息数", style="green")
        table.add_column("创建时间", style="dim")
        table.add_column("最后更新", style="dim")
        
        for session in sessions:
            table.add_row(
                session['name'],
                str(session['message_count']),
                session['created'][:19] if session['created'] else '',
                session['last_updated'][:19] if session['last_updated'] else ''
            )
        
        console.print(table)
    
    def do_load(self, arg: str) -> None:
        """加载指定会话"""
        if not arg.strip():
            console.print("[yellow]请指定会话ID[/yellow]")
            return
        
        if self.session_manager.load_session(arg.strip()):
            # 重新加载上下文文件
            context_files = self.session_manager.get_context_files()
            for ctx_file in context_files:
                self.context_manager.add_file(ctx_file['path'], ctx_file['content'])
            
            # 重新加载历史记录
            history = self.session_manager.get_history()
            self.history = [{"prompt": msg['prompt'], "response": msg['response']} for msg in history]
    
    def do_new(self, arg: str) -> None:
        """创建新会话"""
        session_name = arg.strip() if arg.strip() else None
        session_id = self.session_manager.create_session(session_name)
        
        # 清空当前上下文和历史
        self.context_manager.clear()
        self.history.clear()
    
    def do_checkpoint(self, arg: str) -> None:
        """创建检查点"""
        if not self.session_manager.is_project_initialized():
            console.print("[yellow]当前不在项目目录中，无法创建检查点[/yellow]")
            return
        
        checkpoint_name = arg.strip() if arg.strip() else None
        try:
            checkpoint_id = self.session_manager.create_checkpoint(checkpoint_name)
            console.print(f"[green]检查点创建成功: {checkpoint_id}[/green]")
        except Exception as e:
            console.print(f"[red]创建检查点失败: {e}[/red]")
    
    def do_restore(self, arg: str) -> None:
        """恢复检查点"""
        if not arg.strip():
            console.print("[yellow]请指定检查点ID[/yellow]")
            return
        
        if self.session_manager.restore_checkpoint(arg.strip()):
            # 重新加载上下文文件
            context_files = self.session_manager.get_context_files()
            self.context_manager.clear()
            for ctx_file in context_files:
                self.context_manager.add_file(ctx_file['path'], ctx_file['content'])
            
            # 重新加载历史记录
            history = self.session_manager.get_history()
            self.history = [{"prompt": msg['prompt'], "response": msg['response']} for msg in history]
    
    def do_chat(self, arg: str) -> None:
        """聊天管理命令"""
        if not arg.strip():
            console.print("[yellow]请指定子命令: save, resume, list, delete[/yellow]")
            return
        
        parts = arg.strip().split(' ', 1)
        subcommand = parts[0].lower()
        
        if subcommand == "save":
            if len(parts) < 2:
                console.print("[yellow]请指定标签名称: /chat save <tag>[/yellow]")
                return
            tag = parts[1].strip()
            try:
                checkpoint_id = self.session_manager.create_checkpoint(tag)
                console.print(f"[green]会话已保存为标签: {tag} (ID: {checkpoint_id})[/green]")
            except Exception as e:
                console.print(f"[red]保存会话失败: {e}[/red]")
        
        elif subcommand == "resume":
            if len(parts) < 2:
                console.print("[yellow]请指定标签名称: /chat resume <tag>[/yellow]")
                return
            tag = parts[1].strip()
            try:
                if self.session_manager.restore_checkpoint_by_name(tag):
                    console.print(f"[green]已恢复会话: {tag}[/green]")
                    # 重新加载上下文和历史
                    context_files = self.session_manager.get_context_files()
                    self.context_manager.clear()
                    for ctx_file in context_files:
                        self.context_manager.add_file(ctx_file['path'], ctx_file['content'])
                    
                    history = self.session_manager.get_history()
                    self.history = [{"prompt": msg['prompt'], "response": msg['response']} for msg in history]
                else:
                    console.print(f"[red]未找到标签: {tag}[/red]")
            except Exception as e:
                console.print(f"[red]恢复会话失败: {e}[/red]")
        
        elif subcommand == "list":
            try:
                checkpoints = self.session_manager.list_checkpoints()
                if not checkpoints:
                    console.print("[dim]没有可用的会话标签[/dim]")
                    return
                
                from rich.table import Table
                table = Table(title="可用会话标签", show_header=True, header_style="bold magenta")
                table.add_column("标签", style="cyan")
                table.add_column("创建时间", style="green")
                table.add_column("描述", style="dim")
                
                for checkpoint in checkpoints:
                    table.add_row(
                        checkpoint.get('name', ''),
                        checkpoint.get('created', '')[:19] if checkpoint.get('created') else '',
                        checkpoint.get('description', '')
                    )
                
                console.print(table)
            except Exception as e:
                console.print(f"[red]列出会话标签失败: {e}[/red]")
        
        elif subcommand == "delete":
            if len(parts) < 2:
                console.print("[yellow]请指定要删除的标签: /chat delete <tag>[/yellow]")
                return
            tag = parts[1].strip()
            try:
                if self.session_manager.delete_checkpoint_by_name(tag):
                    console.print(f"[green]已删除会话标签: {tag}[/green]")
                else:
                    console.print(f"[red]未找到标签: {tag}[/red]")
            except Exception as e:
                console.print(f"[red]删除会话标签失败: {e}[/red]")
        
        else:
            console.print("[yellow]未知子命令。可用命令: save, resume, list, delete[/yellow]")
    
    def do_directory(self, arg: str) -> None:
        """目录管理命令"""
        if not arg.strip():
            console.print("[yellow]请指定子命令: add, show[/yellow]")
            return
        
        parts = arg.strip().split(' ', 1)
        subcommand = parts[0].lower()
        
        if subcommand == "add":
            if len(parts) < 2:
                console.print("[yellow]请指定目录路径: /directory add <path>[/yellow]")
                return
            paths = [p.strip() for p in parts[1].split(',')]
            for path in paths:
                try:
                    # 这里可以扩展为实际的工作空间管理
                    console.print(f"[green]已添加目录到工作空间: {path}[/green]")
                except Exception as e:
                    console.print(f"[red]添加目录失败 {path}: {e}[/red]")
        
        elif subcommand == "show":
            # 显示当前工作空间目录
            console.print("[bold]当前工作空间目录:[/bold]")
            console.print(f"  • {os.getcwd()}")
            # 这里可以显示更多工作空间目录
        
        else:
            console.print("[yellow]未知子命令。可用命令: add, show[/yellow]")
    
    def do_memory(self, arg: str) -> None:
        """内存管理命令"""
        if not arg.strip():
            console.print("[yellow]请指定子命令: add, show, refresh, delete, stats[/yellow]")
            return
        
        parts = arg.strip().split(' ', 1)
        subcommand = parts[0].lower()
        
        if subcommand == "add":
            if len(parts) < 2:
                console.print("[yellow]请指定要添加的文本: /memory add <text>[/yellow]")
                return
            
            text = parts[1].strip()
            try:
                # 智能分析文本内容，自动分类
                category = self._analyze_memory_category(text)
                tags = self._extract_memory_tags(text)
                importance = self._assess_memory_importance(text)
                
                memory_id = self.session_manager.add_memory(
                    content=text,
                    category=category,
                    tags=tags,
                    importance=importance
                )
                
                console.print(f"[green]✅ 已添加记忆条目[/green]")
                console.print(f"[dim]ID: {memory_id}[/dim]")
                console.print(f"[dim]分类: {category}[/dim]")
                console.print(f"[dim]标签: {', '.join(tags) if tags else '无'}[/dim]")
                console.print(f"[dim]重要性: {importance}[/dim]")
                
            except Exception as e:
                console.print(f"[red]添加记忆失败: {e}[/red]")
        
        elif subcommand == "show":
            try:
                # 解析可选参数
                category = None
                importance = None
                tags = None
                
                if len(parts) > 1:
                    # 解析筛选参数
                    filter_args = parts[1].strip()
                    if filter_args.startswith("--category="):
                        category = filter_args.split("=", 1)[1]
                    elif filter_args.startswith("--importance="):
                        importance = filter_args.split("=", 1)[1]
                    elif filter_args.startswith("--tags="):
                        tags = filter_args.split("=", 1)[1].split(",")
                
                entries = self.session_manager.get_memory_entries(
                    category=category,
                    tags=tags,
                    importance=importance
                )
                
                if not entries:
                    console.print("[dim]没有找到记忆条目[/dim]")
                    return
                
                # 显示记忆条目
                from rich.table import Table
                table = Table(title="AI 记忆条目", show_header=True, header_style="bold magenta")
                table.add_column("ID", style="cyan", width=20)
                table.add_column("分类", style="green", width=12)
                table.add_column("重要性", style="yellow", width=8)
                table.add_column("内容", style="white", width=50)
                table.add_column("标签", style="dim", width=20)
                table.add_column("访问", style="dim", width=8)
                
                for entry in entries[:20]:  # 限制显示数量
                    content = entry.get("content", "")
                    if len(content) > 47:
                        content = content[:47] + "..."
                    
                    importance_color = {
                        "high": "red",
                        "medium": "yellow", 
                        "low": "green"
                    }.get(entry.get("importance", "medium"), "white")
                    
                    table.add_row(
                        entry.get("id", "")[:18] + "...",
                        entry.get("category", ""),
                        f"[{importance_color}]{entry.get('importance', 'medium')}[/{importance_color}]",
                        content,
                        ", ".join(entry.get("tags", []))[:17] + ("..." if len(", ".join(entry.get("tags", []))) > 17 else ""),
                        str(entry.get("access_count", 0))
                    )
                
                console.print(table)
                
                if len(entries) > 20:
                    console.print(f"[dim]显示前 20 条，共 {len(entries)} 条记忆[/dim]")
                
            except Exception as e:
                console.print(f"[red]显示记忆失败: {e}[/red]")
        
        elif subcommand == "refresh":
            try:
                stats = self.session_manager.refresh_memory()
                console.print("[green]✅ 内存刷新完成[/green]")
                console.print(f"[dim]删除了 {stats['deleted']} 个低价值条目[/dim]")
                console.print(f"[dim]合并了 {stats['merged']} 个相似条目[/dim]")
                
            except Exception as e:
                console.print(f"[red]刷新内存失败: {e}[/red]")
        
        elif subcommand == "delete":
            if len(parts) < 2:
                console.print("[yellow]请指定要删除的记忆ID: /memory delete <id>[/yellow]")
                return
            
            memory_id = parts[1].strip()
            try:
                if self.session_manager.delete_memory(memory_id):
                    console.print(f"[green]✅ 已删除记忆条目: {memory_id}[/green]")
                else:
                    console.print(f"[red]未找到记忆条目: {memory_id}[/red]")
                    
            except Exception as e:
                console.print(f"[red]删除记忆失败: {e}[/red]")
        
        elif subcommand == "stats":
            try:
                stats = self.session_manager.get_memory_stats()
                categories = self.session_manager.get_memory_categories()
                
                from rich.table import Table
                table = Table(title="内存统计信息", show_header=True, header_style="bold magenta")
                table.add_column("项目", style="cyan")
                table.add_column("值", style="green")
                
                table.add_row("总条目数", str(stats.get("total_entries", 0)))
                table.add_row("总访问次数", str(stats.get("total_access_count", 0)))
                table.add_row("平均访问次数", f"{stats.get('average_access_count', 0):.1f}")
                
                # 重要性统计
                importance_stats = stats.get("importance_stats", {})
                table.add_row("高重要性", str(importance_stats.get("high", 0)))
                table.add_row("中等重要性", str(importance_stats.get("medium", 0)))
                table.add_row("低重要性", str(importance_stats.get("low", 0)))
                
                console.print(table)
                
                # 分类统计
                category_stats = stats.get("category_stats", {})
                if category_stats:
                    console.print("\n[bold]分类统计:[/bold]")
                    for category, count in category_stats.items():
                        console.print(f"  • {category}: {count}")
                
                console.print(f"\n[bold]可用分类:[/bold] {', '.join(categories)}")
                
            except Exception as e:
                console.print(f"[red]获取统计信息失败: {e}[/red]")
        
        else:
            console.print("[yellow]未知子命令。可用命令: add, show, refresh, delete, stats[/yellow]")
            console.print("[dim]示例:[/dim]")
            console.print("[dim]  /memory add 这个项目使用Python和FastAPI[/dim]")
            console.print("[dim]  /memory show --category=项目信息[/dim]")
            console.print("[dim]  /memory show --importance=high[/dim]")
            console.print("[dim]  /memory delete mem_20231201_143022_0[/dim]")
    
    def do_generate(self, arg: str) -> None:
        """智能生成项目"""
        if not arg.strip():
            console.print("[yellow]请提供项目描述[/yellow]")
            console.print("[dim]示例: /generate 创建一个JavaScript版本的贪吃蛇游戏[/dim]")
            return
        
        try:
            description = arg.strip()
            console.print(f"[bold]🔍 分析项目需求: {description}[/bold]")
            
            # 分析项目需求
            project_info, tasks = self.project_analyzer.analyze_and_generate_tasks(description)
            
            # 显示分析结果
            summary = self.project_analyzer.get_project_summary(project_info)
            console.print(Panel(summary, title="📋 项目分析结果", border_style="blue"))
            
            # 显示任务列表
            if tasks:
                from rich.table import Table
                table = Table(title="📝 生成任务列表", show_header=True, header_style="bold magenta")
                table.add_column("任务", style="cyan", width=30)
                table.add_column("描述", style="green", width=40)
                table.add_column("优先级", style="yellow", width=10)
                table.add_column("预计时间", style="dim", width=12)
                
                for task in tasks:
                    priority_color = {
                        "high": "red",
                        "medium": "yellow",
                        "low": "green"
                    }.get(task.get("priority", "medium"), "white")
                    
                    table.add_row(
                        task.get("title", ""),
                        task.get("description", ""),
                        f"[{priority_color}]{task.get('priority', 'medium')}[/{priority_color}]",
                        task.get("estimated_time", "")
                    )
                
                console.print(table)
            
            # 询问是否生成项目
            console.print()
            console.print("[bold]🚀 准备生成项目文件...[/bold]")
            
            # 生成项目文件
            generated_files = self.project_generator.generate_project(project_info)
            
            # 显示生成结果
            if generated_files:
                summary = self.project_generator.generate_project_summary(project_info, generated_files)
                console.print(Panel(summary, title="🎉 项目生成完成", border_style="green"))
                
                # 保存到会话记忆
                if self.session_manager.is_project_initialized():
                    self.session_manager.add_memory(
                        content=f"生成了项目: {description}",
                        category="项目信息",
                        tags=["项目生成", "代码生成"],
                        importance="high"
                    )
            else:
                console.print("[red]❌ 项目生成失败[/red]")
                
        except Exception as e:
            console.print(f"[red]项目生成失败: {e}[/red]")
    
    def do_analyze(self, arg: str) -> None:
        """分析项目需求"""
        if not arg.strip():
            console.print("[yellow]请提供项目描述[/yellow]")
            console.print("[dim]示例: /analyze 创建一个React网站应用[/dim]")
            return
        
        try:
            description = arg.strip()
            console.print(f"[bold]🔍 分析项目需求: {description}[/bold]")
            
            # 分析项目需求
            project_info, tasks = self.project_analyzer.analyze_and_generate_tasks(description)
            
            # 显示详细分析结果
            from rich.table import Table
            
            # 基本信息表格
            info_table = Table(title="📋 项目基本信息", show_header=True, header_style="bold magenta")
            info_table.add_column("属性", style="cyan", width=20)
            info_table.add_column("值", style="green", width=30)
            
            info_table.add_row("项目类型", project_info.project_type.value)
            info_table.add_row("复杂度", project_info.complexity.value)
            info_table.add_row("编程语言", ", ".join(project_info.languages) if project_info.languages else "未检测到")
            info_table.add_row("框架", ", ".join(project_info.frameworks) if project_info.frameworks else "无")
            info_table.add_row("功能特性", ", ".join(project_info.features) if project_info.features else "无")
            info_table.add_row("目标平台", project_info.target_platform)
            info_table.add_row("预计文件数", str(project_info.estimated_files))
            
            console.print(info_table)
            
            # 项目结构信息
            if project_info.suggested_structure:
                structure = project_info.suggested_structure
                console.print(f"\n[bold]📁 建议的项目结构:[/bold]")
                console.print(f"• 类型: {structure.get('type', 'unknown')}")
                
                if structure.get('files'):
                    console.print(f"• 文件: {', '.join(structure['files'])}")
                
                if structure.get('directories'):
                    console.print(f"• 目录: {', '.join(structure['directories'])}")
                
                if structure.get('dependencies'):
                    console.print(f"• 依赖: {', '.join(structure['dependencies'])}")
            
            # 任务列表
            if tasks:
                task_table = Table(title="📝 建议的开发任务", show_header=True, header_style="bold magenta")
                task_table.add_column("任务", style="cyan", width=25)
                task_table.add_column("描述", style="green", width=35)
                task_table.add_column("优先级", style="yellow", width=10)
                task_table.add_column("预计时间", style="dim", width=12)
                
                for task in tasks:
                    priority_color = {
                        "high": "red",
                        "medium": "yellow",
                        "low": "green"
                    }.get(task.get("priority", "medium"), "white")
                    
                    task_table.add_row(
                        task.get("title", ""),
                        task.get("description", ""),
                        f"[{priority_color}]{task.get('priority', 'medium')}[/{priority_color}]",
                        task.get("estimated_time", "")
                    )
                
                console.print(f"\n{task_table}")
            
            console.print(f"\n[dim]💡 使用 /generate '{description}' 生成项目文件[/dim]")
            
        except Exception as e:
            console.print(f"[red]项目分析失败: {e}[/red]")
    
    def do_templates(self, arg: str) -> None:
        """显示可用的项目模板"""
        templates_info = """
[bold]📋 支持的项目模板:[/bold]

[green]单页面应用:[/green]
• HTML/CSS/JavaScript 单文件项目
• 适合简单的网页、演示页面
• 示例: "创建一个简单的计算器页面"

[green]游戏项目:[/green]
• Canvas游戏、小游戏
• 包含游戏循环、碰撞检测等
• 示例: "创建一个贪吃蛇游戏"

[green]Web应用:[/green]
• 多页面Web应用
• 支持React、Vue等框架
• 示例: "创建一个React网站应用"

[green]API服务:[/green]
• 后端API服务
• 支持FastAPI、Flask等
• 示例: "创建一个Python API服务"

[green]桌面应用:[/green]
• 桌面GUI应用
• 支持Electron等
• 示例: "创建一个桌面应用"

[green]移动应用:[/green]
• 移动端应用
• 支持React Native、Flutter等
• 示例: "创建一个移动应用"

[green]库/包项目:[/green]
• 可重用的代码库
• 包含文档和测试
• 示例: "创建一个Python工具库"

[green]脚本工具:[/green]
• 自动化脚本
• 命令行工具
• 示例: "创建一个数据处理脚本"

[dim]💡 提示: 使用 /analyze 命令分析您的需求，使用 /generate 命令生成项目[/dim]
        """
        console.print(Panel(templates_info, title="🎨 项目模板", border_style="blue"))
    
    def _analyze_memory_category(self, text: str) -> str:
        """分析文本内容，自动分类"""
        text_lower = text.lower()
        
        # 项目相关关键词
        project_keywords = ["项目", "project", "应用", "app", "系统", "system", "架构", "architecture"]
        if any(keyword in text_lower for keyword in project_keywords):
            return "项目信息"
        
        # 用户偏好关键词
        preference_keywords = ["喜欢", "prefer", "习惯", "习惯", "偏好", "风格", "style"]
        if any(keyword in text_lower for keyword in preference_keywords):
            return "用户偏好"
        
        # 技术要点关键词
        tech_keywords = ["技术", "tech", "算法", "algorithm", "设计模式", "design pattern", "最佳实践", "best practice"]
        if any(keyword in text_lower for keyword in tech_keywords):
            return "技术要点"
        
        # 代码片段关键词
        code_keywords = ["代码", "code", "函数", "function", "类", "class", "方法", "method", "实现", "implement"]
        if any(keyword in text_lower for keyword in code_keywords):
            return "代码片段"
        
        # 默认分类
        return "重要提醒"
    
    def _extract_memory_tags(self, text: str) -> List[str]:
        """从文本中提取标签"""
        tags = []
        text_lower = text.lower()
        
        # 技术标签
        tech_tags = {
            "python": ["python", "py"],
            "javascript": ["javascript", "js", "node"],
            "java": ["java"],
            "go": ["go", "golang"],
            "rust": ["rust"],
            "react": ["react"],
            "vue": ["vue"],
            "fastapi": ["fastapi"],
            "django": ["django"],
            "flask": ["flask"],
            "docker": ["docker"],
            "kubernetes": ["kubernetes", "k8s"],
            "aws": ["aws", "amazon"],
            "gcp": ["gcp", "google cloud"],
            "azure": ["azure", "microsoft"]
        }
        
        for tag, keywords in tech_tags.items():
            if any(keyword in text_lower for keyword in keywords):
                tags.append(tag)
        
        # 概念标签
        concept_tags = {
            "api": ["api", "接口"],
            "database": ["database", "数据库", "db", "sql"],
            "frontend": ["frontend", "前端", "ui", "ux"],
            "backend": ["backend", "后端", "server"],
            "devops": ["devops", "部署", "deploy"],
            "testing": ["test", "测试", "testing"],
            "security": ["security", "安全", "auth", "authentication"]
        }
        
        for tag, keywords in concept_tags.items():
            if any(keyword in text_lower for keyword in keywords):
                tags.append(tag)
        
        return tags[:5]  # 限制标签数量
    
    def _assess_memory_importance(self, text: str) -> str:
        """评估记忆的重要性"""
        text_lower = text.lower()
        
        # 高重要性关键词
        high_importance = ["重要", "important", "关键", "critical", "必须", "must", "注意", "attention"]
        if any(keyword in text_lower for keyword in high_importance):
            return "high"
        
        # 低重要性关键词
        low_importance = ["可能", "maybe", "或许", "perhaps", "临时", "temporary", "测试", "test"]
        if any(keyword in text_lower for keyword in low_importance):
            return "low"
        
        # 根据文本长度判断
        if len(text) > 100:
            return "high"
        elif len(text) < 20:
            return "low"
        
        return "medium"
    
    def do_complete(self, arg: str) -> None:
        """手动补全命令（当 Tab 键不可用时）"""
        if not arg.strip():
            console.print("[yellow]请指定要补全的文本[/yellow]")
            console.print("[dim]示例: /complete mem 或 /complete /mem[/dim]")
            return
        
        text = arg.strip()
        
        # 如果输入以 / 开头，处理斜杠命令补全
        if text.startswith('/'):
            # 移除开头的斜杠
            command_line = text[1:]
            parts = command_line.split()
            
            if not parts:
                # 如果只有斜杠，显示所有可用命令
                commands = self._get_all_commands()
                console.print(f"[bold]以 '/' 开头的命令:[/bold]")
                for i, cmd in enumerate(commands, 1):
                    console.print(f"  {i:2d}. /{cmd}")
                return
            
            command = parts[0].lower()
            
            # 如果正在输入第一个命令
            if len(parts) == 1 and not command_line.endswith(' '):
                commands = self._get_all_commands()
                matches = [cmd for cmd in commands if cmd.startswith(command)]
                
                if matches:
                    console.print(f"[bold]匹配的命令:[/bold]")
                    for i, cmd in enumerate(matches, 1):
                        console.print(f"  {i:2d}. /{cmd}")
                else:
                    console.print(f"[yellow]没有找到以 '{command}' 开头的命令[/yellow]")
                return
            
            # 处理特定命令的子命令补全
            if command in ['chat', 'directory', 'memory']:
                if command == 'chat':
                    subcommands = ['save', 'resume', 'list', 'delete']
                elif command == 'directory':
                    subcommands = ['add', 'show']
                elif command == 'memory':
                    subcommands = ['add', 'show', 'refresh', 'delete', 'stats']
                
                if len(parts) == 2:
                    subcommand = parts[1].lower()
                    matches = [sub for sub in subcommands if sub.startswith(subcommand)]
                    
                    if matches:
                        console.print(f"[bold]/{command} 的子命令:[/bold]")
                        for i, sub in enumerate(matches, 1):
                            console.print(f"  {i:2d}. /{command} {sub}")
                    else:
                        console.print(f"[yellow]没有找到以 '{subcommand}' 开头的子命令[/yellow]")
                        console.print(f"[bold]可用的子命令:[/bold]")
                        for i, sub in enumerate(subcommands, 1):
                            console.print(f"  {i:2d}. /{command} {sub}")
                else:
                    console.print(f"[bold]/{command} 的子命令:[/bold]")
                    for i, sub in enumerate(subcommands, 1):
                        console.print(f"  {i:2d}. /{command} {sub}")
                return
        
        else:
            # 处理普通命令补全
            commands = self._get_all_commands()
            matches = [cmd for cmd in commands if cmd.startswith(text)]
            
            if matches:
                console.print(f"[bold]匹配的命令:[/bold]")
                for i, cmd in enumerate(matches, 1):
                    console.print(f"  {i:2d}. /{cmd}")
            else:
                console.print(f"[yellow]没有找到以 '{text}' 开头的命令[/yellow]")
                console.print(f"[bold]所有可用命令:[/bold]")
                for i, cmd in enumerate(commands, 1):
                    console.print(f"  {i:2d}. /{cmd}")
    
    def do_autocomplete(self, arg: str) -> None:
        """显示自动补全状态和帮助"""
        console.print("[bold]自动补全状态:[/bold]")
        
        if self.readline_available:
            console.print("  ✅ readline 自动补全已启用")
            console.print("  💡 使用方法:")
            console.print("    • 输入 '/' 后按 Tab 查看所有命令")
            console.print("    • 输入 '/mem' 后按 Tab 补全为 '/memory'")
            console.print("    • 输入 '/memory ' 后按 Tab 查看子命令")
        else:
            console.print("  ⚠️ readline 不可用，使用手动补全")
            console.print("  💡 使用方法:")
            console.print("    • 使用 /complete <text> 手动补全命令")
            console.print("    • 例如: /complete mem 或 /complete /mem")
            console.print("    • 例如: /complete /memory 查看子命令")
        
        console.print("\n[bold]示例:[/bold]")
        console.print("  /complete mem     # 查找以 'mem' 开头的命令")
        console.print("  /complete /mem    # 查找以 '/mem' 开头的命令")
        console.print("  /complete /memory # 查看 /memory 的子命令")
    
    # ==================== 自动补全功能 ====================
    
    def complete(self, text: str, state: int) -> Optional[str]:
        """
        重写 cmd.Cmd 的 complete 方法，实现自定义自动补全
        
        Args:
            text: 当前输入的文本
            state: 补全状态（0=开始，1+=继续）
            
        Returns:
            补全建议或 None
        """
        try:
            # 获取当前输入行
            line = readline.get_line_buffer()
        except AttributeError:
            # 如果 readline.get_line_buffer 不可用，使用备用方法
            # 在这种情况下，我们无法准确判断用户输入，使用默认补全
            return super().complete(text, state)
        
        # 处理斜杠命令补全的多种情况
        if text.startswith('/'):
            # 情况1: text 以 / 开头，直接处理斜杠命令
            return self._complete_slash_command(text[1:], state, text)
        elif line.startswith('/'):
            # 情况2: line 以 / 开头，处理斜杠命令
            return self._complete_slash_command(text, state, line)
        elif not line and text == "":
            # 情况3: 空输入，可能是用户刚输入了 '/' 后按 Tab
            # 在 readline 中，当用户输入 '/' 后立即按 Tab，get_line_buffer() 可能返回空字符串
            return self._complete_slash_command("", state, "/")
        # 否则使用默认补全
        return None
    
    def _complete_slash_command(self, text: str, state: int, line: str) -> Optional[str]:
        """
        处理斜杠命令的自动补全
        
        Args:
            text: 当前输入的文本
            state: 补全状态
            line: 完整的输入行
            
        Returns:
            补全建议或 None
        """
        # 移除开头的斜杠
        command_line = line[1:]
        
        # 分割命令和参数
        parts = command_line.split()
        
        # 如果只有斜杠或者正在输入第一个命令
        if not parts or (len(parts) == 1 and not command_line.endswith(' ')):
            commands = self._get_all_commands()
            result = self._filter_completions(commands, text, state)
            # 如果找到了匹配的命令，返回完整的斜杠命令
            if result:
                return f"/{result}"
            return result
        
        command = parts[0].lower()
        
        # 处理特定命令的子命令补全
        if command in ['chat', 'directory', 'memory']:
            subcommand_result = self._complete_subcommand(command, parts, text, state)
            if subcommand_result is not None:
                return subcommand_result
        
        # 处理其他命令的参数补全
        return self._complete_command_args(command, parts, text, state)
    
    def _get_all_commands(self) -> List[str]:
        """获取所有可用的斜杠命令"""
        return [
            'analyze', 'ask', 'about', 'autocomplete', 'chat', 'checkpoint', 'clear', 'complete',
            'config', 'copy', 'directory', 'exclude', 'exit', 'files', 'generate', 'help', 'history',
            'include', 'init', 'load', 'memory', 'model', 'new', 'provider',
            'quit', 'read', 'restore', 'session', 'sessions', 'settings',
            'stats', 'templates', 'tools', 'write'
        ]
    
    def _complete_subcommand(self, command: str, parts: List[str], text: str, state: int) -> Optional[str]:
        """补全子命令"""
        if command == 'chat':
            subcommands = ['save', 'resume', 'list', 'delete']
        elif command == 'directory':
            subcommands = ['add', 'show']
        elif command == 'memory':
            subcommands = ['add', 'show', 'refresh', 'delete', 'stats']
        else:
            return None
        
        # 如果正在输入子命令
        if len(parts) == 2:
            return self._filter_completions(subcommands, text, state)
        
        # 如果命令后面有空格，根据 state 返回不同的子命令
        if len(parts) == 1 and text == "":
            if state < len(subcommands):
                return subcommands[state]
            return None
        
        return None
    
    def _complete_command_args(self, command: str, parts: List[str], text: str, state: int) -> Optional[str]:
        """补全命令参数"""
        if command == 'memory' and len(parts) >= 2:
            subcommand = parts[1].lower()
            
            if subcommand == 'show':
                # 补全筛选参数
                if text.startswith('--'):
                    filters = ['--category=', '--importance=', '--tags=']
                    return self._filter_completions(filters, text, state)
                elif '--category=' in text:
                    # 补全分类选项
                    categories = self.session_manager.get_memory_categories()
                    return self._filter_completions(categories, text.split('=')[-1], state)
                elif '--importance=' in text:
                    # 补全重要性选项
                    importance_levels = ['high', 'medium', 'low']
                    return self._filter_completions(importance_levels, text.split('=')[-1], state)
        
        elif command == 'model':
            # 补全模型名称（这里可以扩展为从配置中读取可用模型）
            models = ['gpt-3.5-turbo', 'gpt-4', 'claude-3-sonnet', 'claude-3-haiku']
            return self._filter_completions(models, text, state)
        
        elif command == 'provider':
            # 补全提供商名称
            providers = ['openrouter', 'ollama', 'siliconflow']
            return self._filter_completions(providers, text, state)
        
        return None
    
    def _filter_completions(self, completions: List[str], text: str, state: int) -> Optional[str]:
        """
        过滤补全建议
        
        Args:
            completions: 所有可能的补全
            text: 当前输入的文本
            state: 补全状态
            
        Returns:
            匹配的补全建议或 None
        """
        # 过滤匹配的补全
        matches = [comp for comp in completions if comp.startswith(text)]
        
        # 返回指定状态的匹配项
        if state < len(matches):
            return matches[state]
        
        return None
    
    def _setup_readline(self) -> None:
        """设置 readline 配置"""
        try:
            # 设置补全函数
            readline.set_completer(self.complete)
            
            # 设置补全分隔符（移除斜杠，这样斜杠不会被当作分隔符）
            readline.set_completer_delims(' \t\n')
            
            # 启用历史记录和补全
            readline.parse_and_bind("tab: complete")
            readline.parse_and_bind("set show-all-if-unmodified on")
            readline.parse_and_bind("set show-all-if-ambiguous on")
            
            # 设置历史文件
            history_file = os.path.expanduser("~/.minicoder_history")
            try:
                readline.read_history_file(history_file)
            except FileNotFoundError:
                pass
            
            # 注册退出时保存历史
            import atexit
            atexit.register(readline.write_history_file, history_file)
            
            console.print("[dim]💡 自动补全已启用，输入 '/' 后按 Tab 查看命令[/dim]")
            self.readline_available = True
            
        except Exception as e:
            # 如果 readline 不可用，启用备用方案
            console.print(f"[dim]⚠️ readline 不可用，启用备用自动补全功能[/dim]")
            self.readline_available = False
    
    def start(self) -> None:
        """启动交互式会话"""
        # 设置 readline 自动补全
        self._setup_readline()
        
        try:
            self.cmdloop()
        except KeyboardInterrupt:
            console.print("\n[yellow]会话已中断[/yellow]")
        except EOFError:
            console.print("\n[yellow]会话已结束[/yellow]")
    
    def do_settings(self, arg: str) -> None:
        """打开设置编辑器"""
        console.print("[bold]设置编辑器[/bold]")
        console.print("[dim]设置编辑器功能待实现[/dim]")
        console.print("当前配置:")
        info = self.ai_model.get_model_info()
        console.print(f"  提供商: {info['provider']}")
        console.print(f"  模型: {info['model']}")
    
    def do_tools(self, arg: str) -> None:
        """显示可用工具"""
        console.print("[bold]可用工具:[/bold]")
        tools = [
            "文件管理器 - 读取、写入、管理文件",
            "上下文管理器 - 管理对话上下文",
            "会话管理器 - 管理会话状态和持久化",
            "提示词构建器 - 构建和优化提示词",
            "AI模型接口 - 与各种AI服务交互"
        ]
        for tool in tools:
            console.print(f"  • {tool}")
    
    def do_copy(self, arg: str) -> None:
        """复制最后输出到剪贴板"""
        if not self.history:
            console.print("[yellow]没有可复制的输出[/yellow]")
            return
        
        last_response = self.history[-1]["response"]
        try:
            import subprocess
            import sys
            
            if sys.platform == "darwin":  # macOS
                subprocess.run(["pbcopy"], input=last_response, text=True, check=True)
            elif sys.platform == "win32":  # Windows
                subprocess.run(["clip"], input=last_response, text=True, check=True)
            else:  # Linux
                subprocess.run(["xclip", "-selection", "clipboard"], input=last_response, text=True, check=True)
            
            console.print("[green]已复制最后输出到剪贴板[/green]")
        except Exception as e:
            console.print(f"[red]复制失败: {e}[/red]")
            console.print("[dim]请确保系统已安装剪贴板工具 (xclip/xsel on Linux, pbcopy on macOS, clip on Windows)[/dim]")
    
    def do_stats(self, arg: str) -> None:
        """显示会话统计信息"""
        from rich.table import Table
        
        table = Table(title="会话统计信息", show_header=True, header_style="bold magenta")
        table.add_column("项目", style="cyan")
        table.add_column("值", style="green")
        
        # 基本统计
        table.add_row("会话消息数", str(len(self.history)))
        table.add_row("上下文文件数", str(len(self.context_manager.get_files())))
        table.add_row("当前提供商", self.config.get_provider())
        table.add_row("当前模型", self.config.get_model())
        
        # 项目信息
        if self.session_manager.is_project_initialized():
            session_info = self.session_manager.get_session_info()
            if session_info:
                table.add_row("项目目录", session_info.get('project_dir', ''))
                table.add_row("会话ID", session_info.get('id', ''))
        
        console.print(table)
    
    def do_about(self, arg: str) -> None:
        """显示版本信息"""
        from . import __version__
        about_text = f"""
[bold]MiniCoder CLI[/bold]
版本: {__version__}
描述: 轻量级、高效且可扩展的命令行AI编程助手

[bold]特性:[/bold]
• 多模型支持 (SiliconFlow, OpenRouter, Ollama)
• 会话持久化
• 项目级上下文管理
• 类似Gemini CLI的命令结构

[bold]技术栈:[/bold]
• Python 3.8+
• Click (命令行界面)
• Rich (美化输出)
• YAML (配置管理)

[dim]请在报告问题时分享此信息[/dim]
        """
        console.print(Panel(about_text.strip(), title="关于 MiniCoder CLI", border_style="blue"))
    
    def do_init(self, arg: str) -> None:
        """初始化项目工作目录"""
        try:
            from pathlib import Path
            import yaml
            
            # 检查是否已经在项目目录中
            if self.session_manager.is_project_initialized():
                console.print("[yellow]当前目录已经是项目目录[/yellow]")
                console.print("[dim]使用 /new 创建新会话，或 /sessions 查看现有会话[/dim]")
                return
            
            # 创建 .minicoder 目录
            minicoder_dir = Path(".minicoder")
            minicoder_dir.mkdir(exist_ok=True)
            
            # 创建子目录
            (minicoder_dir / "sessions").mkdir(exist_ok=True)
            (minicoder_dir / "checkpoints").mkdir(exist_ok=True)
            (minicoder_dir / "generated").mkdir(exist_ok=True)
            
            # 创建项目配置文件
            project_config = {
                "project": {
                    "name": Path.cwd().name,
                    "created": str(Path.cwd()),
                    "description": "MiniCoder CLI 项目工作目录"
                },
                "session": {
                    "auto_save": True,
                    "max_history": 50,
                    "checkpoint_interval": 10
                },
                "code_generation": {
                    "auto_save_code": True,
                    "code_output_dir": ".minicoder/generated",
                    "backup_original": True
                }
            }
            
            config_file = minicoder_dir / "config.yaml"
            with open(config_file, 'w', encoding='utf-8') as f:
                yaml.dump(project_config, f, default_flow_style=False, allow_unicode=True)
            
            # 创建 .gitignore 条目
            gitignore_file = Path(".gitignore")
            gitignore_entry = "\n# MiniCoder CLI\n.minicoder/\n"
            
            if gitignore_file.exists():
                with open(gitignore_file, 'r', encoding='utf-8') as f:
                    content = f.read()
                if ".minicoder/" not in content:
                    with open(gitignore_file, 'a', encoding='utf-8') as f:
                        f.write(gitignore_entry)
            else:
                with open(gitignore_file, 'w', encoding='utf-8') as f:
                    f.write(f"# MiniCoder CLI{gitignore_entry}")
            
            console.print("[green]✅ 项目工作目录初始化成功！[/green]")
            
            # 显示项目信息
            project_info = Panel(
                f"[bold]📁 项目目录:[/bold] {Path.cwd()}\n"
                f"[bold]🔧 配置文件:[/bold] {config_file}\n"
                f"[bold]💾 会话存储:[/bold] {minicoder_dir / 'sessions'}\n"
                f"[bold]📝 代码输出:[/bold] {minicoder_dir / 'generated'}\n"
                f"[bold]🔄 检查点:[/bold] {minicoder_dir / 'checkpoints'}\n\n"
                "[bold]✨ 新功能:[/bold]\n"
                "• 会话历史自动保存\n"
                "• 代码生成自动保存\n"
                "• 项目级上下文管理\n"
                "• 检查点恢复功能",
                title="🎉 项目初始化完成",
                border_style="green",
                padding=(1, 2)
            )
            console.print(project_info)
            
            # 重新初始化会话管理器以识别新项目
            self.session_manager = SessionManager()
            if self.session_manager.is_project_initialized():
                self.session_manager.create_session()
                console.print("[green]已创建新会话[/green]")
            
        except Exception as e:
            console.print(f"[red]项目初始化失败: {e}[/red]")
    
    def do_question(self, arg: str) -> None:
        """显示帮助信息 (/? 命令)"""
        self.do_help(arg)
    
    def do_quit(self, arg: str) -> bool:
        """退出会话"""
        # 保存会话
        if self.session_manager.is_project_initialized():
            self.session_manager.save_session()
            console.print("[green]会话已保存[/green]")
        
        console.print("[yellow]再见！[/yellow]")
        return True
    
    def do_exit(self, arg: str) -> bool:
        """退出会话"""
        return self.do_quit(arg)
    
    def default(self, line: str) -> bool:
        """处理默认输入（直接作为提示词或斜杠命令）"""
        if line.strip():
            # 检查是否是斜杠命令
            if line.strip().startswith('/'):
                return self._handle_slash_command(line.strip())
            else:
                self._process_prompt(line.strip())
        return False
    
    def _handle_slash_command(self, command: str) -> bool:
        """处理斜杠命令，返回是否应该退出"""
        # 移除开头的斜杠
        command = command[1:]
        
        # 分割命令和参数
        parts = command.split(' ', 1)
        cmd = parts[0].lower()
        arg = parts[1] if len(parts) > 1 else ""
        
        # 处理各种斜杠命令
        if cmd == "help" or cmd == "?":
            self.do_help(arg)
        elif cmd == "clear":
            self.do_clear(arg)
        elif cmd == "quit" or cmd == "exit":
            return self.do_quit(arg)  # 返回退出状态
        elif cmd == "config":
            self.do_config(arg)
        elif cmd == "model":
            self.do_model(arg)
        elif cmd == "provider":
            self.do_provider(arg)
        elif cmd == "session":
            self.do_session(arg)
        elif cmd == "sessions":
            self.do_sessions(arg)
        elif cmd == "load":
            self.do_load(arg)
        elif cmd == "new":
            self.do_new(arg)
        elif cmd == "checkpoint":
            self.do_checkpoint(arg)
        elif cmd == "restore":
            self.do_restore(arg)
        elif cmd == "include":
            self.do_include(arg)
        elif cmd == "exclude":
            self.do_exclude(arg)
        elif cmd == "files":
            self.do_files(arg)
        elif cmd == "read":
            self.do_read(arg)
        elif cmd == "write":
            self.do_write(arg)
        elif cmd == "history":
            self.do_history(arg)
        elif cmd == "ask":
            self.do_ask(arg)
        elif cmd == "chat":
            self.do_chat(arg)
        elif cmd == "directory":
            self.do_directory(arg)
        elif cmd == "memory":
            self.do_memory(arg)
        elif cmd == "settings":
            self.do_settings(arg)
        elif cmd == "tools":
            self.do_tools(arg)
        elif cmd == "agent":
            self.do_agent(arg)
        elif cmd == "mode":
            self.do_mode(arg)
        elif cmd == "copy":
            self.do_copy(arg)
        elif cmd == "stats":
            self.do_stats(arg)
        elif cmd == "about":
            self.do_about(arg)
        elif cmd == "init":
            self.do_init(arg)
        elif cmd == "generate":
            self.do_generate(arg)
        elif cmd == "analyze":
            self.do_analyze(arg)
        elif cmd == "templates":
            self.do_templates(arg)
        else:
            console.print(f"[red]未知命令: /{cmd}[/red]")
            console.print("[dim]输入 /help 查看可用命令[/dim]")
        
        return False  # 默认不退出
    
    def _process_prompt(self, prompt: str) -> None:
        """处理提示词"""
        try:
            if self.agent_mode and self.agent:
                # Agent 模式：使用智能 Agent 处理
                self._process_with_agent(prompt)
            else:
                # 传统模式：直接使用 AI 模型
                self._process_with_traditional_mode(prompt)
            
        except Exception as e:
            console.print(f"[red]错误: {e}[/red]")
    
    def _process_with_agent(self, prompt: str) -> None:
        """使用 Agent 处理提示词"""
        # 构建上下文
        context = {
            'files': self.context_manager.get_files(),
            'project_path': str(self.session_manager.project_dir) if self.session_manager.is_project_initialized() else None
        }
        
        # 使用 Agent 处理查询
        response = self.agent.process_query(prompt, context)
        
        # 保存到历史（向后兼容）
        self.history.append({
            "prompt": prompt,
            "response": response
        })
        
        # 保存到持久化会话
        if self.session_manager.is_project_initialized():
            # 添加消息到会话
            self.session_manager.add_message(prompt, response)
        
        # 显示响应
        console.print("\n[bold green]🤖 Agent 响应:[/bold green]")
        console.print(response)
        console.print()  # 空行
    
    def _process_with_traditional_mode(self, prompt: str) -> None:
        """使用传统模式处理提示词"""
        # 构建完整提示词
        final_prompt = self.prompt_builder.build_prompt(
            prompt=prompt,
            context_files=self.context_manager.get_files()
        )
        
        # 发送请求
        if self.stream:
            # 流式输出（打字机效果）
            console.print("🤖 AI 响应:")
            console.print()
            
            # 定义回调函数
            def typing_callback(chunk: str):
                import sys
                sys.stdout.write(chunk)
                sys.stdout.flush()
            
            # 使用回调函数生成响应
            response = self.ai_model.generate_with_callback(final_prompt, typing_callback, stream=True)
            console.print()  # 换行
        else:
            # 普通输出
            status_msg = "[bold green]正在生成响应..." + (" (流式)" if self.stream else "")
            with console.status(status_msg):
                response = self.ai_model.generate(final_prompt, stream=self.stream)
        
        # 保存到历史（向后兼容）
        self.history.append({
            "prompt": prompt,
            "response": response
        })
        
        # 保存到持久化会话
        if self.session_manager.is_project_initialized():
            # 添加消息到会话
            self.session_manager.add_message(prompt, response)
        
        # 显示响应
        console.print("\n[bold green]AI 响应:[/bold green]")
        console.print(response)
        console.print()  # 空行
    
    def do_agent(self, arg: str) -> None:
        """Agent 相关命令"""
        if not arg.strip():
            # 显示 Agent 状态
            if self.agent_mode and self.agent:
                self.agent.display_status()
            else:
                console.print("[yellow]Agent 模式未启用[/yellow]")
            return
        
        parts = arg.strip().split(' ', 1)
        cmd = parts[0].lower()
        arg = parts[1] if len(parts) > 1 else ""
        
        if cmd == "status":
            if self.agent_mode and self.agent:
                self.agent.display_status()
            else:
                console.print("[yellow]Agent 模式未启用[/yellow]")
        
        elif cmd == "history":
            if self.agent_mode and self.agent:
                history = self.agent.get_conversation_history()
                if history:
                    console.print("[bold]Agent 对话历史:[/bold]")
                    for i, conv in enumerate(history[-5:], 1):  # 显示最近5轮
                        console.print(f"\n[cyan]{i}. 用户:[/cyan] {conv['user']}")
                        console.print(f"[green]Agent:[/green] {conv['agent'][:100]}...")
                else:
                    console.print("[dim]没有对话历史[/dim]")
            else:
                console.print("[yellow]Agent 模式未启用[/yellow]")
        
        elif cmd == "clear":
            if self.agent_mode and self.agent:
                self.agent.clear_history()
            else:
                console.print("[yellow]Agent 模式未启用[/yellow]")
        
        elif cmd == "suggest":
            if self.agent_mode and self.agent:
                if arg:
                    suggestions = self.agent.suggest_tools(arg)
                    if suggestions:
                        console.print(f"[bold]建议的工具:[/bold] {', '.join(suggestions)}")
                    else:
                        console.print("[dim]没有找到合适的工具建议[/dim]")
                else:
                    console.print("[yellow]请提供查询内容[/yellow]")
            else:
                console.print("[yellow]Agent 模式未启用[/yellow]")
        
        else:
            console.print("[red]未知的 agent 子命令[/red]")
            console.print("[dim]可用命令: status, history, clear, suggest[/dim]")
    
    def do_mode(self, arg: str) -> None:
        """切换模式"""
        if not arg.strip():
            # 显示当前模式
            mode = "Agent 模式" if self.agent_mode else "传统模式"
            console.print(f"[bold]当前模式:[/bold] {mode}")
            return
        
        mode = arg.strip().lower()
        
        if mode in ["agent", "智能", "smart"]:
            if not self.agent_mode:
                try:
                    self.tool_manager = ToolManager()
                    self.agent = MiniCoderAgent(self.ai_model, self.tool_manager)
                    self.agent_mode = True
                    console.print("[green]✓ 已切换到 Agent 模式[/green]")
                    # 更新提示符
                    self._update_prompt()
                except Exception as e:
                    console.print(f"[red]切换到 Agent 模式失败: {e}[/red]")
            else:
                console.print("[yellow]已经在 Agent 模式[/yellow]")
        
        elif mode in ["traditional", "传统", "classic"]:
            if self.agent_mode:
                self.agent_mode = False
                self.agent = None
                self.tool_manager = None
                console.print("[green]✓ 已切换到传统模式[/green]")
                # 更新提示符
                self._update_prompt()
            else:
                console.print("[yellow]已经在传统模式[/yellow]")
        
        else:
            console.print("[red]未知模式[/red]")
            console.print("[dim]可用模式: agent, traditional[/dim]")
    
    def _update_prompt(self) -> None:
        """更新命令提示符"""
        stream_indicator = " (stream)" if self.stream else ""
        project_indicator = " [项目]" if self.session_manager.is_project_initialized() else ""
        agent_indicator = " [Agent]" if self.agent_mode else ""
        self.prompt = f"minicoder({self.config.get_provider()}){stream_indicator}{project_indicator}{agent_indicator}> "
